#![no_std]
#![no_main]
extern crate alloc;

use alloc::boxed::Box;
use alloc::format;
use alloc::rc::Rc;
use alloc::string::ToString;
use alloc::vec::Vec;
use core::cell::RefCell;
use core::fmt::Debug;
use core::sync::atomic::{AtomicBool, Ordering};
use critical_section::Mutex;
use embassy_executor::Spawner;
use embassy_time::Timer;
use embedded_graphics::mono_font::ascii::FONT_10X20;
use embedded_graphics::mono_font::iso_8859_7::FONT_5X8;
use embedded_graphics::mono_font::MonoTextStyle;
use embedded_graphics::prelude::Primitive;
use embedded_graphics::primitives::PrimitiveStyle;
use embedded_graphics::text::Text;
use embedded_graphics_core::Drawable;
use embedded_graphics_core::pixelcolor::{Bgr565, BinaryColor, Rgb565};
use embedded_graphics_core::prelude::{DrawTarget, ImageDrawable, Point, RgbColor, Size};
use embedded_graphics_core::primitives::Rectangle;
use embedded_hal::delay::DelayNs;
use embedded_hal_bus::spi::{ExclusiveDevice, NoDelay};
use esp_hal::clock::{CpuClock, RadioClockController};
use esp_hal::delay::Delay;
use esp_hal::{handler, main, ram, spi, Blocking};
use esp_hal::gpio::{Event, Input, InputConfig, Io, Level, Output, OutputConfig, Pull};
use esp_hal::i2c::master::I2c;
use esp_hal::peripherals::Peripherals;
use esp_hal::rtc_cntl::Rtc;
use esp_hal::spi::master::Config;
use esp_hal::spi::master::Spi;
use esp_hal::spi::Mode;
use esp_hal::time::{Duration, Instant, Rate};
use esp_hal::timer::systimer::SystemTimer;
use esp_hal::timer::timg::TimerGroup;
use esp_println::logger::{init_logger, init_logger_from_env};
use esp_println::println;
use log::{error, info, warn, LevelFilter};
use mipidsi::{Builder, Display};
use mipidsi::interface::SpiInterface;
use mipidsi::models::ST7789;
use mipidsi::options::{ColorInversion, Orientation};
use slint::platform::{Platform, WindowAdapter};
use slint::platform::software_renderer::{LineBufferProvider, MinimalSoftwareWindow, Rgb565Pixel};
use slint::{invoke_from_event_loop, ModelRc, PhysicalSize, PlatformError, Rgb8Pixel, Rgba8Pixel, SharedPixelBuffer, TimerMode, Weak};
slint::include_modules!();

#[panic_handler]
fn panic(info: &core::panic::PanicInfo) -> ! {
    error!("panic:{}",info);
    loop {}
}

#[esp_hal_embassy::main]
async fn main(spawner: Spawner) {
    // generator version: 0.3.1
    // init_logger_from_env();
    init_logger(LevelFilter::Debug);
    esp_alloc::heap_allocator!(size: 100 * 1024);
    info!("分配内存完成");

    let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max());
    let peripherals =esp_hal::init(config);

    // 配置异步
    let timer0 = SystemTimer::new(peripherals.SYSTIMER);
    esp_hal_embassy::init(timer0.alarm0);


    let mut delay = Delay::new();

    let mut rst = Output::new(peripherals.GPIO3,Level::Low,OutputConfig::default());
    rst.set_high();

    let dc = Output::new(peripherals.GPIO4,Level::Low,OutputConfig::default());
    let mut backlight = Output::new(peripherals.GPIO5,Level::Low,OutputConfig::default());

    let sclk = peripherals.GPIO6;
    let sda = peripherals.GPIO7;
    let sdi = peripherals.GPIO8;
    let cs = peripherals.GPIO10;


    let spi = Spi::new(peripherals.SPI2,
                       Config::default()
                           .with_mode(Mode::_3)
                           .with_frequency(Rate::from_mhz(60))
    ).unwrap()
        .with_sck(sclk)
        .with_miso(sdi)
        .with_mosi(sda);


    let cs_output = Output::new(cs,Level::High,OutputConfig::default());
    let spi_device =  ExclusiveDevice::new_no_delay(spi,cs_output).unwrap();

    let di = SpiInterface::new(spi_device,dc,unsafe{ &mut BUFFER });
    let display = Builder::new(ST7789, di)
        .display_size(240,240)
        .invert_colors(ColorInversion::Inverted)
        .color_order(mipidsi::options::ColorOrder::Rgb) // mipidsi 默认是 RGB 顺序，但你的屏幕是 BGR 的 你需要告诉 mipidsi 使用 BGR 颜色顺序
        .orientation(Orientation::new().flip_vertical().flip_horizontal())
        // .orientation(Orientation::new())
        .reset_pin(rst)
        .init(&mut delay).unwrap();

    println!("display 初始化完成");
    backlight.set_high();

    info!("开启异步任务");
    spawner.spawn(ui_run(display)).ok();

    // for inspiration have a look at the examples at https://github.com/esp-rs/esp-hal/tree/esp-hal-v1.0.0-beta.0/examples/src/bin
}
static mut BUFFER: [u8; 512] = [0_u8; 512];


type DISPLAY = Display<SpiInterface<'static, ExclusiveDevice<Spi<'static,Blocking>,Output<'static>,NoDelay>,Output<'static>>,ST7789,Output<'static>>;

#[embassy_executor::task]
async fn ui_run(mut display: DISPLAY){
    // 创建平台实例
    let window = MinimalSoftwareWindow::new(
        slint::platform::software_renderer::RepaintBufferType::ReusedBuffer,
    );
    window.set_size(PhysicalSize::new(240,240));
    let platform = EspPlatform::new(window.clone());
    slint::platform::set_platform(Box::new(platform)).unwrap();

    // 创建ui
    let ui = MainView::new().unwrap();
    ui.window().set_size(PhysicalSize::new(240,240));

    // let ui_weak = ui.as_weak();
    // spawner.spawn(ui_task(ui_weak)).ok();

    info!("进入了loop run");
    // 初始化显示
    display.clear(Rgb565::BLACK).unwrap();
    info!("清理屏幕");

    // 创建行缓冲区
    let display_width = 240; // 根据实际显示宽度设置
    let mut the_frame_buffer = [Rgb565Pixel(0); 240 ]; // 128x64
    // let mut the_frame_buffer = [Rgb565Pixel(0); 240 * 240]; // 128x64

    let mut time = Instant::now();;
    let mut last_frame_time = time.duration_since_epoch();
    let mut fps = 0;
    let mut frame_count = 0;
    loop {
        frame_count+=1;

        // 更新UI状态
        slint::platform::update_timers_and_animations();
        // info!("window has activie {}",window.has_active_animations());
        // 渲染UI
        window.draw_if_needed(|renderer| {

            renderer.render_by_line(FrameBuffer{ frame_buffer: &mut the_frame_buffer, stride: display_width,display:&mut display });

        });

        // === FPS 计算 ===
        let now = time.duration_since_epoch();
        if now.as_millis()-last_frame_time.as_millis() >= 1000{
            last_frame_time = now;
            fps = frame_count;
            frame_count = 0;

            // 清除上一次FPS显示区域
            Rectangle::new(Point::new(0, 0), Size::new(80, 30))
                .into_styled(PrimitiveStyle::with_fill(Rgb565::BLACK))
                .draw(&mut display)
                .unwrap();

            // 绘制新的FPS文本
            let text_style = MonoTextStyle::new(&FONT_10X20, Rgb565::WHITE);
            let fps_text = format!("FPS: {}", fps);
            Text::new(&fps_text, Point::new(10, 20), text_style)
                .draw(&mut display)
                .unwrap();
        }

        // 根据动画状态决定是否延迟
        if !window.has_active_animations() {
            if let Some(duration) = slint::platform::duration_until_next_timer_update(){
                Timer::after_millis(duration.as_millis() as u64).await;
                continue;
            }
        }
        Timer::after_millis(10).await;
    }
}



// 平台实现结构体
struct EspPlatform{
    window: Rc<MinimalSoftwareWindow>,
}

impl EspPlatform {
    fn new(window:Rc<MinimalSoftwareWindow>) -> Self {
        Self {
            window
        }
    }
}


/// 实现 Platform trait
impl Platform for EspPlatform {
    fn create_window_adapter(&self) -> Result<Rc<dyn WindowAdapter>, PlatformError> {
        info!("成功创建了window");
        Ok(self.window.clone())
    }

    fn duration_since_start(&self) -> core::time::Duration {
        // 使用定时器获取时间（需要实际硬件计时器实现）
        let time = Instant::now().duration_since_epoch().as_millis();
        // info!("time :{}",time);
        core::time::Duration::from_millis(
            time
        )
    }
}


struct FrameBuffer<'a>{ frame_buffer: &'a mut [Rgb565Pixel], stride: usize,display:&'a mut DISPLAY }
impl<'a> LineBufferProvider for FrameBuffer<'a> {
    type TargetPixel = Rgb565Pixel;
    fn process_line(
        &mut self,
        line: usize,
        range: core::ops::Range<usize>,
        render_fn: impl FnOnce(&mut [Self::TargetPixel]),
    ) {
        // let line_start = line * self.stride;
        // let line_pixels = &mut self.frame_buffer[line_start..line_start + 128];
        // info!("process_line {}",line);
        let buf = &mut self.frame_buffer[range.clone()];
        // render_fn(&mut self.frame_buffer[range.clone()]);
        render_fn(buf);
        // warn!("设置后的：{:?}",buf);
        // 31 蓝(青色) 63488 红（黄色）  1024 绿色（紫色）

        self.display.set_pixels(
            range.start as u16,
            line as _,
            range.end as u16,
            line as u16,
            buf.iter().map(|x|{
                embedded_graphics_core::pixelcolor::raw::RawU16::new(x.0).into()
            })
        ).unwrap()


    }
}


